package org.ee.core.util;


import java.time.*;
import java.time.format.DateTimeFormatter;

/**
 * 日期时间工具
 * 主要功能
 *
 * 获取当前时间：
 *
 * getCurrentDate(): 获取当前日期（yyyy-MM-dd）。
 *
 * getCurrentTime(): 获取当前时间（HH:mm:ss）。
 *
 * getCurrentDateTime(): 获取当前日期时间（yyyy-MM-dd HH:mm:ss）。
 *
 * getCurrentDateTimeWithMillis(): 获取当前日期时间，带毫秒（yyyy-MM-dd HH:mm:ss.SSS）。
 *
 * 格式化和解析日期时间：
 *
 * formatDate(LocalDate date, String pattern): 格式化 LocalDate 为指定格式。
 *
 * parseDate(String dateStr, String pattern): 将字符串解析为 LocalDate。
 *
 * 同样支持 LocalTime 和 LocalDateTime。
 *
 * 时间戳转换：
 *
 * getCurrentTimestamp(): 获取当前时间戳（毫秒）。
 *
 * toTimestamp(LocalDateTime dateTime): 将 LocalDateTime 转换为时间戳（毫秒）。
 *
 * fromTimestamp(long timestamp): 将时间戳（毫秒）转换为 LocalDateTime。
 *
 * 日期和时间比较：
 *
 * isEqual(LocalDateTime dateTime1, LocalDateTime dateTime2): 判断两个 LocalDateTime 是否相等。
 *
 * isBeforeToday(LocalDateTime dateTime): 判断日期是否在今天之前。
 *
 * isAfterToday(LocalDateTime dateTime): 判断日期是否在今天之后。
 *
 * 日期差：
 *
 * getDateDifference(LocalDate date1, LocalDate date2): 获取两个日期之间的天数差。
 *
 * getTimeDifference(LocalTime time1, LocalTime time2): 获取两个时间之间的秒数差。
 *
 * getDateTimeDifference(LocalDateTime dateTime1, LocalDateTime dateTime2): 获取两个日期时间之间的秒数差。
 *
 * 时区转换：
 *
 * convertToUTC(LocalDateTime localDateTime): 转换为 UTC 时间。
 *
 * getCurrentUTCDateTime(): 获取当前 UTC 时间。
 *
 * convertToTimeZone(LocalDateTime localDateTime, ZoneId zoneId): 将 LocalDateTime 转换为指定时区的时间。
 *
 * convertToTimeZone(LocalDateTime localDateTime, String timeZone): 将 LocalDateTime 转换为指定时区的时间（通过时区字符串）。
 *
 * 日期字符串转换：
 *
 * parseToDate(String dateStr, String pattern): 将字符串转换为 Date 类型。
 *
 * formatDateToString(Date date, String pattern): 将 Date 转换为指定格式的字符串。
 * @Author jokr
 * @Date 2025/8/26 下午1:45
 */

public class DateTimeUtil {

    // 常用日期格式
    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static final String TIME_PATTERN = "HH:mm:ss";
    public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";

    // 获取当前日期
    public static String getCurrentDate() {
        return formatDate(LocalDate.now(), DATE_PATTERN);
    }

    // 获取当前时间
    public static String getCurrentTime() {
        return formatDate(LocalTime.now(), TIME_PATTERN);
    }

    // 获取当前日期时间
    public static String getCurrentDateTime() {
        return formatDate(LocalDateTime.now(), DATETIME_PATTERN);
    }

    // 获取当前日期时间，带毫秒
    public static String getCurrentDateTimeWithMillis() {
        return formatDate(LocalDateTime.now(), DATETIME_MS_PATTERN);
    }

    // 格式化日期
    public static String formatDate(LocalDate date, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return date.format(formatter);
    }

    public static String formatDate(LocalTime time, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return time.format(formatter);
    }

    public static String formatDate(LocalDateTime dateTime, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return dateTime.format(formatter);
    }

    // 将字符串转换为日期
    public static LocalDate parseDate(String dateStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDate.parse(dateStr, formatter);
    }

    public static LocalTime parseTime(String timeStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalTime.parse(timeStr, formatter);
    }

    public static LocalDateTime parseDateTime(String dateTimeStr, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(dateTimeStr, formatter);
    }

    // 获取当前时间戳（毫秒）
    public static long getCurrentTimestamp() {
        return System.currentTimeMillis();
    }

    // 获取当前时间的 Unix 时间戳（秒）
    public static long getCurrentUnixTimestamp() {
        return Instant.now().getEpochSecond();
    }

    // 将日期转换为时间戳（毫秒）
    public static long toTimestamp(LocalDateTime dateTime) {
        return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    // 将时间戳（毫秒）转换为日期
    public static LocalDateTime fromTimestamp(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
    }

    // 获取日期差
    public static long getDateDifference(LocalDate date1, LocalDate date2) {
        return java.time.temporal.ChronoUnit.DAYS.between(date1, date2);
    }

    // 获取时间差（秒）
    public static long getTimeDifference(LocalTime time1, LocalTime time2) {
        return java.time.temporal.ChronoUnit.SECONDS.between(time1, time2);
    }

    // 获取日期时间差（秒）
    public static long getDateTimeDifference(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        return java.time.temporal.ChronoUnit.SECONDS.between(dateTime1, dateTime2);
    }

    // 获取当前时区的时间
    public static ZonedDateTime getCurrentZonedDateTime() {
        return ZonedDateTime.now();
    }

    // 转换为 UTC 时间
    public static ZonedDateTime convertToUTC(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC);
    }

    // 获取 UTC 当前时间
    public static ZonedDateTime getCurrentUTCDateTime() {
        return ZonedDateTime.now(ZoneOffset.UTC);
    }

    // 获取当前日期（不带时间）
    public static LocalDate getToday() {
        return LocalDate.now();
    }

    // 获取当前时间（不带日期）
    public static LocalTime getCurrentLocalTime() {
        return LocalTime.now();
    }

    // 判断两个日期是否相等
    public static boolean isEqual(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        return dateTime1.isEqual(dateTime2);
    }

    // 判断日期是否在今天之前
    public static boolean isBeforeToday(LocalDateTime dateTime) {
        return dateTime.isBefore(LocalDateTime.now().toLocalDate().atStartOfDay());
    }

    // 判断日期是否在今天之后
    public static boolean isAfterToday(LocalDateTime dateTime) {
        return dateTime.isAfter(LocalDateTime.now().toLocalDate().atStartOfDay());
    }

    // 获取某个日期的开始时间（00:00:00）
    public static LocalDateTime getStartOfDay(LocalDate date) {
        return date.atStartOfDay();
    }

    // 获取某个日期的结束时间（23:59:59.999）
    public static LocalDateTime getEndOfDay(LocalDate date) {
        return date.atTime(LocalTime.MAX);
    }

    // 获取当前月的第一天
    public static LocalDate getFirstDayOfMonth() {
        return LocalDate.now().withDayOfMonth(1);
    }

    // 获取当前月的最后一天
    public static LocalDate getLastDayOfMonth() {
        return LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth());
    }

    // 获取某周的第一天（周一）
    public static LocalDate getFirstDayOfWeek() {
        return LocalDate.now().with(DayOfWeek.MONDAY);
    }

    // 获取某周的最后一天（周日）
    public static LocalDate getLastDayOfWeek() {
        return LocalDate.now().with(DayOfWeek.SUNDAY);
    }

    // 根据日期获取星期几
    public static String getDayOfWeek(LocalDate date) {
        return date.getDayOfWeek().name();
    }

    // 判断一个日期是否是闰年
    public static boolean isLeapYear(int year) {
        return Year.isLeap(year);
    }

    // 日期加天数
    public static LocalDate addDays(LocalDate date, long days) {
        return date.plusDays(days);
    }

    // 日期减天数
    public static LocalDate subtractDays(LocalDate date, long days) {
        return date.minusDays(days);
    }

    // 日期加月数
    public static LocalDate addMonths(LocalDate date, long months) {
        return date.plusMonths(months);
    }

    // 日期减月数
    public static LocalDate subtractMonths(LocalDate date, long months) {
        return date.minusMonths(months);
    }

    // 日期加年数
    public static LocalDate addYears(LocalDate date, long years) {
        return date.plusYears(years);
    }

    // 日期减年数
    public static LocalDate subtractYears(LocalDate date, long years) {
        return date.minusYears(years);
    }

}
